package com.project.service.impl;

import com.achievement.service.impl.AllAchievementServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.entity.bo.SciencePersonBo;
import com.base.entity.vo.SciencePersonVo;
import com.base.service.SciencePersonService;
import com.common.core.domain.AjaxResult;
import com.common.core.domain.entity.SysUser;
import com.common.utils.QueryWrapperUtils;
import com.common.utils.SecurityUtils;
import com.common.utils.StringUtils;
import com.common.utils.bean.BizProcessMessages;
import com.common.utils.uuid.IdUtils;
import com.feemanage.domain.BizProjectFeeCard;
import com.feemanage.domain.BizProjectIncome;
import com.feemanage.domain.BizProjectOutboundMain;
import com.feemanage.domain.BizProjectPayout;
import com.feemanage.domain.bo.ProjectTypeExecuteBo;
import com.feemanage.domain.vo.BizProjectOutboundMainVo;
import com.feemanage.service.ISysSnruleService;
import com.feemanage.service.impl.*;
import com.common.core.page.PageDomain;
import com.project.domain.bo.*;
import com.project.domain.entity.*;
import com.project.domain.entity.xjProject.BizXjProject;
import com.project.domain.entity.xjProject.BizXjProjectDocument;
import com.project.domain.entity.xjProject.BizXjProjectMember;
import com.project.domain.entity.zxProject.BizZxProject;
import com.project.domain.entity.zxProject.BizZxProjectDocument;
import com.project.domain.entity.zxProject.BizZxProjectMember;
import com.project.domain.vo.*;
import com.project.mapper.ProjectInitMapper;
import com.project.mapper.YfContractMemberMapper;
import com.project.mapper.xjProject.XjProjectMapper;
import com.project.mapper.zxProject.ZxProjectMapper;
import com.project.service.IBuyerContractService;
import com.project.service.IProjectInitService;
import com.project.service.IYfContractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service("biz_zx_project")
public class ProjectInitServiceImpl implements IProjectInitService {

    @Autowired
    ProjectInitMapper projectInitMapper;

    @Autowired
    XjProjectMapper xjProjectMapper;

    @Autowired
    ZxProjectMapper zxProjectMapper;

    @Autowired
    SciencePersonService sciencePersonService;

    @Autowired
    ProjectMemberServiceImpl memberService;

    @Autowired
    ProjectCooperationUnitServiceImpl projectCooperationUnitService;

    @Autowired
    ProjectInSchoolServiceImpl projectInSchoolService;

    @Autowired
    BudgetStandardServiceImpl budgetStandardService;

    @Autowired
    ProjectBudgetServiceImpl budgetService;

    @Autowired
    ProjectDocumentServiceImpl documentService;

    @Autowired
    ProjectMiddleCheckServiceImpl middleCheckService;

    @Autowired
    CompleteProServiceImpl completeProService;

    @Autowired
    AlterationServiceImpl alterationService;

    @Autowired
    AllAchievementServiceImpl allAchievementService;


    //横向进账记录
    @Autowired
    IYfContractService yfProjectService;
    //横向出账记录
    @Autowired
    IBuyerContractService buyerContractService;
    //横向项目成员
    @Autowired
    private YfContractMemberMapper yfContractMemberMapper;

    @Autowired
    ProjectTypeServiceImpl projectTypeService;

    @Autowired
    private ISysSnruleService sysSnruleService;
    

    //经费相关
    @Autowired
    BizProjectFeeCardServiceImpl feeCardService;

    @Autowired
    BizProjectIncomeServiceImpl incomeService;

    @Autowired
    BizProjectOutboundMainServiceImpl outboundMainService;

    @Autowired
    BizProjectPayoutServiceImpl payoutService;

    @Autowired
    ProjectTypeExecuteServiceImpl executeService;

    @Autowired
    private ProCheckCommon checkCommon;


    /**
     * 左上角根据状态的数量统计
     * @param projectInfoBo
     * @return
     */
    public List<NavigationForProVo.NameAndCount> selectGroups(ProjectInfoBo projectInfoBo){
        List<NavigationForProVo.NameAndCount> res = new ArrayList<>();
        try {
            QueryWrapper<NavigationForProVo.NameAndCount> queryWrapper = new QueryWrapper<>();
            queryWrapper = this.getConditions(queryWrapper,projectInfoBo,"group");
            QueryWrapperUtils.getParams_project(queryWrapper,SecurityUtils.getLoginUser().getUser(),"select");
            res = projectInitMapper.selectGroups(queryWrapper,projectInfoBo);
        }catch (Exception exception){
            String ex = exception.getMessage();
        }
        return res;
    }

    /**
     * 获取科研人员-科研项目列表左侧导航栏
     * @return
     */
    public List<NavigationForProVo> getProNavigation(){
        List<NavigationForProVo> res = new ArrayList<>();
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
//        String userId  = "2c97a3549424ba180194251665790001";
        String userId  = loginUser.getUserId().toString();

        try {
            String proIds = this.getProIdsByUserNow(loginUser.getUserId().toString(),"join");
//            String proIds = this.getProIdsByUserNow(userId,"");

            //所有
            NavigationForProVo navigationAll = new NavigationForProVo();
            navigationAll.setNavigationName("所有");
            res.add(navigationAll);

            //项目性质
            NavigationForProVo navigationClass = new NavigationForProVo();
            navigationClass.setNavigationName("项目性质");
            navigationClass.setNavigationValue("PROJECT_CLASS");
            navigationClass.setClassCounts(projectInitMapper.getCountsByGroup("PROJECT_CLASS",proIds));
            res.add(navigationClass);

            //参与形式
            NavigationForProVo navigationJoin = new NavigationForProVo();
            navigationJoin.setNavigationName("参与形式");
            navigationJoin.setNavigationValue("BEAR_TYPE_ID");
            navigationJoin.setClassCounts(projectInitMapper.getCountsByGroup("BEAR_TYPE_ID",userId));
            res.add(navigationJoin);

            //项目状态
            NavigationForProVo navigationStatus = new NavigationForProVo();
            navigationStatus.setNavigationName("项目状态");
            navigationStatus.setNavigationValue("PROJECT_STATUS_ID");
            navigationStatus.setClassCounts(projectInitMapper.getCountsByGroup("PROJECT_STATUS_ID",proIds));
            res.add(navigationStatus);

            //年度分布
            NavigationForProVo navigationYear = new NavigationForProVo();
            navigationYear.setNavigationName("年度分布");
            navigationYear.setNavigationValue("AUTHORIZE_DATE");
            navigationYear.setClassCounts(projectInitMapper.getCountsByGroup("AUTHORIZE_DATE",proIds));
            res.add(navigationYear);
        }catch (Exception exception){
            String ex = exception.getMessage();
        }

        return res;
    }

    /**
     * 获取项目各页签上方信息
     * @param proId
     * @return
     */
    public ProInitOtherBaseInfoVo getProotherBase(String proId){
        try{
            return projectInitMapper.getOtherInfos(proId);
        }catch (Exception exception){
            return new ProInitOtherBaseInfoVo();
        }
    }


    /**
     * 项目立项列表
     * @param projectInfoBo
     * @param type
     * @return
     */
    @Override
    public IPage<ProListInfoVo> getProList(ProjectInfoBo projectInfoBo, String type){
        IPage<ProListInfoVo> res = new Page<>();

        try{
            QueryWrapper<ProListInfoVo> queryWrapper = new QueryWrapper<>();
            queryWrapper = this.getConditions(queryWrapper,projectInfoBo,"list");
            QueryWrapperUtils.getParams_project(queryWrapper,SecurityUtils.getLoginUser().getUser(),type);
            //处理排序字段
            String orderStr = StringUtils.isNotBlank(projectInfoBo.getOrderStr())?projectInfoBo.getOrderStr():"createdate";
            String orderType = StringUtils.isNotBlank(projectInfoBo.getOrderType())?projectInfoBo.getOrderType():"desc";
            projectInfoBo.setOrderStr(this.changeStringToUp(orderStr));
            projectInfoBo.setOrderType(orderType);

            String proClass = projectInfoBo.getProClass();
            String listType = proClass.equals("xJProject")?"校级项目立项":proClass.equals("zXProject")?"纵向项目立项":proClass.equals("yfContract")?"进账合同签订":null;
            if(type.equals("select")){
                IPage<ProListInfoVo> myPage = new Page<>(projectInfoBo.getPageNo(), projectInfoBo.getPageSize());
                IPage<ProListInfoVo> list = projectInitMapper.getProList(myPage, queryWrapper,projectInfoBo);
                if(StringUtils.isNotBlank(listType)){
                    res = middleCheckService.getCheckInfosForList(list,listType,ProListInfoVo::setTaskId,ProListInfoVo::setIsAuditor,ProListInfoVo::getProcessInstanceId);
                }else{
                    res= list;
                }
            }else{
                IPage<ProListInfoVo> myPage = new Page<>(1, 10000);
                if(proClass.equals("xJProject")){
                    res = projectInitMapper.getXjExportList(myPage,queryWrapper,projectInfoBo);
                }else if(proClass.equals("zXProject")){
                    res = projectInitMapper.getZxExportList(myPage,queryWrapper,projectInfoBo);
                }else{
                    res = projectInitMapper.getYfExportList(myPage,queryWrapper,projectInfoBo);
                }
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
        }

        return  res;
    }

    private QueryWrapper getConditions(QueryWrapper queryWrapper,ProjectInfoBo projectInfoBo,String funcType){
        //处理立项日期
        String startAuthorizeDate = changeDateString(projectInfoBo.getStartAuthorizeDate(),"start");
        String endAuthorizeDate = changeDateString(projectInfoBo.getEndAuthorizeDate(),"end");

        //处理开始日期字段（年份4、年月7、年月日）
        String startBeginDate = changeDateString(projectInfoBo.getStartBeginDate(),"start");
        String endBeginData = changeDateString(projectInfoBo.getEndBeginDate(),"end");

        //处理计划结项日期字段（年份4、年月7、年月日）
        String startPlanEndDate = changeDateString(projectInfoBo.getStartPlanEndDate(),"start");
        String endPlanEndDate = changeDateString(projectInfoBo.getEndPlanEndDate(),"end");

        //处理金额
        BigDecimal maxTotalMoney = StringUtils.isNotBlank(projectInfoBo.getMaxTotalMoney())?BigDecimal.valueOf(Float.parseFloat(projectInfoBo.getMaxTotalMoney()) * 10000):null;
        BigDecimal minTotalMoney = StringUtils.isNotBlank(projectInfoBo.getMinTotalMoney())?BigDecimal.valueOf(Float.parseFloat(projectInfoBo.getMinTotalMoney()) * 10000):null;

        projectInfoBo.setProjectTypeCode(addQuotationToStr(projectInfoBo.getProjectTypeCode()));//处理项目分类id
        projectInfoBo.setUnitId(addQuotationToStr(projectInfoBo.getUnitId()));//处理所属单位id
        projectInfoBo.setProjectStatusId(addQuotationToStr(projectInfoBo.getProjectStatusId()));//处理项目状态id
        projectInfoBo.setProjectLevelId(addQuotationToStr(projectInfoBo.getProjectLevelId()));//处理项目级别id
        projectInfoBo.setCheckstatus(addQuotationToStr(projectInfoBo.getCheckstatus()));//处理审核状态id
        projectInfoBo.setProjectSourceId(addQuotationToStr(projectInfoBo.getProjectSourceId()));//处理项目状态id

        queryWrapper.like(StringUtils.isNotBlank(projectInfoBo.getChargerName()), "CHARGER_NAME", projectInfoBo.getChargerName())
                .ge(StringUtils.isNotBlank(startAuthorizeDate), "AUTHORIZE_DATE", startAuthorizeDate)
                .le(StringUtils.isNotBlank(endAuthorizeDate), "AUTHORIZE_DATE", endAuthorizeDate)
                .le(StringUtils.isNotBlank(projectInfoBo.getMaxTotalMoney()), "FEE_AUTHORIZE", maxTotalMoney)
                .ge(StringUtils.isNotBlank(projectInfoBo.getMinTotalMoney()), "FEE_AUTHORIZE", minTotalMoney)
                .like(StringUtils.isNotBlank(projectInfoBo.getAuthorizeCode()), "AUTHORIZE_CODE", projectInfoBo.getAuthorizeCode())
                .like(StringUtils.isNotBlank(projectInfoBo.getChargerPhone()), "CHARGER_PHONE", projectInfoBo.getChargerPhone())
                .like(StringUtils.isNotBlank(projectInfoBo.getChargerEmail()), "CHARGER_EMAIL", projectInfoBo.getChargerEmail())
                .like(StringUtils.isNotBlank(projectInfoBo.getTransactor()), "TRANSACTOR", projectInfoBo.getTransactor())
                .like(StringUtils.isNotBlank(projectInfoBo.getTransactorPhone()), "TRANSACTOR_PHONE", projectInfoBo.getTransactorPhone())
                .ge(StringUtils.isNotBlank(startBeginDate), "BEGIN_DATE", startBeginDate)
                .le(StringUtils.isNotBlank(endBeginData), "BEGIN_DATE", endBeginData)
                .ge(StringUtils.isNotBlank(startPlanEndDate), "PLAN_END_DATE", startPlanEndDate)
                .le(StringUtils.isNotBlank(endPlanEndDate), "PLAN_END_DATE", endPlanEndDate)
                .eq(StringUtils.isNotBlank(projectInfoBo.getCooperateId()), "COOPERATE_ID", projectInfoBo.getCooperateId())
                .like(StringUtils.isNotBlank(projectInfoBo.getBuyerTel()),"BUYER_TEL",projectInfoBo.getBuyerTel())
                .like(StringUtils.isNotBlank(projectInfoBo.getBuyerName()),"BUYER_NAME",projectInfoBo.getBuyerName())
                .like(StringUtils.isNotBlank(projectInfoBo.getBuyerChargerName()),"BUYER_CHARGER_NAME",projectInfoBo.getBuyerChargerName());

        if(funcType.equals("list")){
            queryWrapper.eq(StringUtils.isNotBlank(projectInfoBo.getCheckstatusByGroup()), "zb.CHECKSTATUS", projectInfoBo.getCheckstatusByGroup());
        }
        return queryWrapper;
    }

    /**
     * 当前用户作为成员的项目
     * @param userId
     * @return
     */
    public String getProIdsByUserNow(String userId,String joinType){
        String res = "";
        try {
            VProjectMemberBo vProjectMemberBo = new VProjectMemberBo();
            vProjectMemberBo.setPersonId(userId);
            if(StringUtils.isNotBlank(joinType)){
                if(joinType.equals("charge")){
                    //当前用户作为负责人的项目
                    vProjectMemberBo.setBearTypeId("1");
                }else{
                    //当前用户作为参与人的项目
                    vProjectMemberBo.setBearTypeId("2','3");
                }
            }

            List<BizZxProjectMember> memberList = memberService.getMemList(vProjectMemberBo);
            if(memberList != null && memberList.size()>0){
                List<String> proIds = new ArrayList<>();
                memberList.forEach(memberInfo->proIds.add(memberInfo.getProjectId()));
                res = proIds.stream().collect(Collectors.joining("','"));
            }
        }catch (Exception exception){

        }

        return res;
    }

    //region 查询
    /**
     * 查询基础信息
     * @param proId
     * @return
     */
    @Override
    public VProject baseDetail(String proId){
        QueryWrapper<VProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ID",proId);
        VProject res = projectInitMapper.selectOne(queryWrapper);

        //处理金额单位为万元(批准经费、配套经费、外拨经费、自筹经费)
        if(res != null){
            res.setFeeAuthorize(this.changeMoneyQuantifier(res.getFeeAuthorize(),"/"));
            res.setAttachFee(this.changeMoneyQuantifier(res.getAttachFee(),"/"));
            res.setOutFee(this.changeMoneyQuantifier(res.getOutFee(),"/"));
            res.setSelfProvideFee(this.changeMoneyQuantifier(res.getSelfProvideFee(),"/"));
        }
        return res;
    }

    /**
     * 查询基础信息
     * @param proId
     * @return
     */
    @Override
    public BizXjProject xjDetail(String proId){
        QueryWrapper<BizXjProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ID",proId);
        BizXjProject res = xjProjectMapper.selectOne(queryWrapper);

        if(res != null){
            //处理金额单位为万元(批准经费、配套经费、外拨经费、自筹经费)
            res.setFeeAuthorize(this.changeMoneyQuantifier(res.getFeeAuthorize(),"/"));
            res.setAttachFee(this.changeMoneyQuantifier(res.getAttachFee(),"/"));
            res.setOutFee(this.changeMoneyQuantifier(res.getOutFee(),"/"));
            res.setSelfProvideFee(this.changeMoneyQuantifier(res.getSelfProvideFee(),"/"));

            //处理时间仅保留年月日
            res.setAuthorizeDate(this.subeDateStr(res.getAuthorizeDate()));
            res.setBeginDate(this.subeDateStr(res.getBeginDate()));
            res.setPlanEndDate(this.subeDateStr(res.getPlanEndDate()));
            res.setActualEndDate(this.subeDateStr(res.getActualEndDate()));
        }
        return res;
    }

    /**
     * 查询基础信息
     * @param proId
     * @return
     */
    @Override
    public BizZxProject zxDetail(String proId){
        QueryWrapper<BizZxProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ID",proId);
        BizZxProject res = zxProjectMapper.selectOne(queryWrapper);

        //处理金额单位为万元(批准经费、配套经费、外拨经费、自筹经费)
        if(res != null){
            res.setFeeAuthorize(this.changeMoneyQuantifier(res.getFeeAuthorize(),"/"));
            res.setAttachFee(this.changeMoneyQuantifier(res.getAttachFee(),"/"));
            res.setOutFee(this.changeMoneyQuantifier(res.getOutFee(),"/"));
            res.setSelfProvideFee(this.changeMoneyQuantifier(res.getSelfProvideFee(),"/"));

            //处理时间仅保留年月日
            res.setAuthorizeDate(this.subeDateStr(res.getAuthorizeDate()));
            res.setBeginDate(this.subeDateStr(res.getBeginDate()));
            res.setPlanEndDate(this.subeDateStr(res.getPlanEndDate()));
            res.setActualEndDate(this.subeDateStr(res.getActualEndDate()));
        }
        return res;
    }

    /**
     * 查询校级项目成员信息
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectMemberInfoVo memDetail(String proId){
        String proClass = this.getProClassByProId(proId);
        ProjectMemberInfoVo projectMemberInfoVo = new ProjectMemberInfoVo();
        projectMemberInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"member"));

        List<BizZxProjectMember> memberList = new ArrayList<>();
        List<BizYfContractMember> YfMemberList = new ArrayList<>();
        if(proClass.equals("xJProject")){
            memberList = xjMemberList(proId);
        }else if(proClass.equals("zXProject")){
            memberList = zxMemberList(proId);
        }else if(proClass.equals("yfContract")){
           YfMemberList = hxMemberList(proId);
        }

        projectMemberInfoVo.setBizZxProjectMemberList(memberList);
        projectMemberInfoVo.setBizHxProjectMemberList(YfMemberList);
        return projectMemberInfoVo;
    }

    /**
     * 查询校级项目成员信息
     * @param proId 项目号
     * @return
     */
    public List<BizZxProjectMember> xjMemberList(String proId){
        //成员列表
        List<BizZxProjectMember> memberList = new ArrayList<>();
        VProjectMemberBo memBo = new VProjectMemberBo();
        memBo.setProjectId(proId);
        memBo.setProClass("xJProject");
        memberList = memberService.getMemList(memBo);
        if(memberList == null || memberList !=null && memberList.size()<=0){
            BizXjProject baseInfo = xjProjectMapper.selectById(proId);
            SciencePersonVo sciencePersonVo = new SciencePersonVo();
            sciencePersonVo.setId(baseInfo.getChargerCode());
            List<SciencePersonBo> sciencePersons = sciencePersonService.personDetails(sciencePersonVo);//根据负责人id获取负责人详情

            BizZxProjectMember proMember = new BizZxProjectMember();
            proMember.setPersonName(baseInfo.getChargerName());
            proMember.setPersonId(baseInfo.getChargerCode());
            proMember.setUnitId(sciencePersons.get(0).getUnitId());
            proMember.setBearTypeId("1");
            memberList.add(proMember);
        }

        return memberList;
    }

    /**
     * 查询纵向项目成员信息
     * @param proId 项目号
     * @return
     */
    public List<BizZxProjectMember> zxMemberList(String proId){
        //成员信息
        List<BizZxProjectMember> memberList = new ArrayList<>();
        VProjectMemberBo memBo = new VProjectMemberBo();
        memBo.setProjectId(proId);
        memBo.setProClass("zXProject");
        memberList= memberService.getMemList(memBo);
        if(memberList == null || memberList != null && memberList.size() <= 0){
            BizZxProject baseInfo = zxProjectMapper.selectById(proId);
            SciencePersonVo sciencePersonVo = new SciencePersonVo();
            sciencePersonVo.setId(baseInfo.getChargerCode());
            List<SciencePersonBo> sciencePersons = sciencePersonService.personDetails(sciencePersonVo);//根据负责人id获取负责人详情

            BizZxProjectMember proMember = new BizZxProjectMember();
            proMember.setPersonName(baseInfo.getChargerName());
            proMember.setPersonId(baseInfo.getChargerCode());
            proMember.setUnitId(sciencePersons.get(0).getUnitId());
            proMember.setBearTypeId("1");
            memberList.add(proMember);
        }

        return memberList;
    }

    /**
     * 查询横向项目成员信息
     * @param proId 项目号
     * @return
     */
    public List<BizYfContractMember> hxMemberList(String proId){
        LambdaQueryWrapper<BizYfContractMember> query=new LambdaQueryWrapper<>();
        query.orderBy(true,true,BizYfContractMember::getOrderId);
        query.eq(BizYfContractMember::getContractId,proId);
        return   yfContractMemberMapper.selectList(query);
    }



    /**
     * 查询纵向项目校内课题信息
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectKetiInfoVo zxKetiDetail(String proId){
        ProjectKetiInfoVo projectKetiInfoVo = new ProjectKetiInfoVo();
        projectKetiInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"keTi"));

        //校内课题
        BizProjectInSchool bizProjectInSchool = new BizProjectInSchool();
        bizProjectInSchool.setProjectId(proId);
        projectKetiInfoVo.setBizProjectInSchoolList(projectInSchoolService.selectBizProjectInSchoolList(bizProjectInSchool));
        return projectKetiInfoVo;
    }

    /**
     * 查询纵向项目合作单位信息
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectCooperationUnitInfoVo zxCooperationUnitDetail(String proId){
        ProjectCooperationUnitInfoVo projectCooperationUnitInfoVo = new ProjectCooperationUnitInfoVo();
        projectCooperationUnitInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"cooperationUnit"));

        //合作单位信息
        BizProjectCooperationUnit unitBo = new BizProjectCooperationUnit();
        unitBo.setProjectId(proId);
        List<BizProjectCooperationUnit> bizProjectCooperationUnitList = projectCooperationUnitService.selectBizProjectCooperationUnitListNew(proId);
        projectCooperationUnitInfoVo.setBizProjectCooperationUnitList(bizProjectCooperationUnitList);

        //经费外拨信息
        projectCooperationUnitInfoVo.setOutboundMainVoList(this.getOutBoundList(proId));

        return projectCooperationUnitInfoVo;
    }

    /**
     * 获取经费外拨信息
     * @param proId
     * @return
     */
    public List<BizProjectOutboundMainVo> getOutBoundList(String proId){
        try{
            PageDomain pageDomain = new PageDomain();
            pageDomain.setPageNum(1);
            pageDomain.setPageSize(1000);
            BizProjectOutboundMain main = new BizProjectOutboundMain();
            main.setProjectId(proId);
            return outboundMainService.selectList(pageDomain,main).getRecords();
        }catch (Exception exception){
            return  null;
        }
    }

    /**
     * 预算信息
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectBudgetInfoVo budgetDetail(String proId){
        ProjectBudgetInfoVo projectBudgetInfoVo = new ProjectBudgetInfoVo();
        projectBudgetInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"budget"));

        //单独获取一下预算时间
        BizProjectBudgetBatch bizProjectBudgetBatch = new BizProjectBudgetBatch();
        bizProjectBudgetBatch.setProjectId(proId);
        BizProjectBudgetBatch budgetBatch = budgetService.selectBizProjectBudgetBatch(bizProjectBudgetBatch);
        if(budgetBatch!= null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            projectBudgetInfoVo.setBudgetDate(budgetBatch.getBudgetDate() != null
                    ? sdf.format(budgetBatch.getBudgetDate())
                    : null);
//            projectBudgetInfoVo.setBudgetDate(budgetBatch.getBudgetDate() !=null?budgetBatch.getBudgetDate().toString():null);
        }

        //预算信息
        //轮流写入经费信息和变更信息
        try{
            //预算科目
            DmBudgetStandardVo dmBudgetStandardVo = new DmBudgetStandardVo();
            VProject base = baseDetail(proId);
            dmBudgetStandardVo = budgetStandardService.selectDmBudgetStandardByID(base.getBudgetStandardId());
            if(dmBudgetStandardVo != null){
                List<DmBudgetSubject> subjectList = dmBudgetStandardVo.getSubjectList();

                //经费信息
                List<BudgetFeeVo> feeList = budgetService.selectBudgetFeeInfo(proId);
                //变更信息
                List<BudgetAlterationHistoryVo> changeList = alterationService.getBudgetChangeListByProId(proId);
                if(feeList != null && feeList.size()>0){
                    Map<String,BudgetFeeVo> budgetFeeMap = feeList.stream().collect(Collectors.toMap(BudgetFeeVo::getId, item->item));
                    if(changeList != null && changeList.size()>0){
                        Map<String,BudgetAlterationHistoryVo> changeMap = changeList.stream().collect(Collectors.toMap(BudgetAlterationHistoryVo::getId, item->item));
                        subjectList.forEach(node -> assignValueToNode(node,budgetFeeMap,changeMap));
                    }else{
                        subjectList.forEach(node -> assignValueToNode(node,budgetFeeMap,null));
                    }
                }

                projectBudgetInfoVo.setBizProjectBudgetFeeList(subjectList);
            }else{
                projectBudgetInfoVo.setBizProjectBudgetFeeList(null);
            }

            //预算进度信息
            ProjectTypeExecuteBo executeBo = new ProjectTypeExecuteBo();
            executeBo.setProjectId(proId);
            projectBudgetInfoVo.setBudgetExecuteVoList(executeService.selectbudgetList(executeBo));

        }catch (Exception exception){
            String str = exception.getMessage();
        }


        return projectBudgetInfoVo;
    }

    /**
     * 根据subject的id从映射中检索对应的Fee对象
     * @param subjects 预算科目
     * @param budgetFeeMap 预算费用
     */
    public static void assignValueToNode(DmBudgetSubject subjects,Map<String,BudgetFeeVo> budgetFeeMap,Map<String,BudgetAlterationHistoryVo> changeMap){
        BudgetFeeVo budgetFeeVo = budgetFeeMap.get(subjects.getCode());
        BudgetAlterationHistoryVo budgetAlterationHistoryVo = new BudgetAlterationHistoryVo();

        if(budgetFeeVo != null){
            //经费相关
            subjects.setFeeRatio(budgetFeeVo.getFeeRatio());
            subjects.setZcMoney(budgetFeeVo.getZcMoney());
            subjects.setPtMoney(budgetFeeVo.getPtMoney());
            subjects.setLxMoney(budgetFeeVo.getLxMoney());
            subjects.setWbMoney(budgetFeeVo.getWbMoney());
            subjects.setZxMoney(budgetFeeVo.getZxMoney());
            subjects.setYfFee(budgetFeeVo.getYfFee());

            //需要给变更前金额赋值，变更后金额和变更前金额一致
            subjects.setBeforeAlterBudgetFee(budgetFeeVo.getLxMoney());
            subjects.setAfterAlterBudgetFee(budgetFeeVo.getLxMoney());

            //变更相关
            if(changeMap != null){
                budgetAlterationHistoryVo = changeMap.get(subjects.getCode());
                subjects.setInitVal(budgetAlterationHistoryVo.getInitVal());
                subjects.setChangeMoneyHis(budgetAlterationHistoryVo.getChangeMoneyHis());
                subjects.setChangeTimeHis(budgetAlterationHistoryVo.getChangeTimeHis());
            }
        }
        subjects.getChildren().forEach(child->assignValueToNode(child,budgetFeeMap,changeMap));
    }

    /**
     * 经费信息
     * @param proId 项目号
     * @return
     */
    public ProjectMoneyInfoVo moneyDetail(String proId){
        ProjectMoneyInfoVo projectMoneyInfoVo = new ProjectMoneyInfoVo();
        projectMoneyInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"money"));
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageSize(1000);
        pageDomain.setPageNum(1);

        /** 经费卡 */
        BizProjectFeeCard feeCard = new BizProjectFeeCard();
        feeCard.setProjectId(proId);
        projectMoneyInfoVo.setFeeCardList(feeCardService.selectList(pageDomain, feeCard).getRecords());

        /** 经费入账 */
        BizProjectIncome claim = new BizProjectIncome();
        claim.setProjectId(proId);
        projectMoneyInfoVo.setInComeVoList(incomeService.selectList(pageDomain,claim).getRecords());

        /** 经费外拨 */
        projectMoneyInfoVo.setOutboundMainVoList(this.getOutBoundList(proId));

        /** 经费报销 */
        BizProjectPayout payout = new BizProjectPayout();
        payout.setProjectId(proId);
        projectMoneyInfoVo.setPayoutVoList(payoutService.selectList(pageDomain,payout).getRecords());

        return projectMoneyInfoVo;
    }

    /**
     * 出账合同
     * @param proId 项目号
     * @return
     */
    public ProjectBuyerInfoVo buyerDetail(String proId){
        ProjectBuyerInfoVo projectBuyerInfoVo = new ProjectBuyerInfoVo();
        projectBuyerInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"buyer"));

        //出账合同
        BizBuyerContractBo bizBuyerContractBo = new BizBuyerContractBo();
        bizBuyerContractBo.setSourceProjectID(proId);
        projectBuyerInfoVo.setBuyerContractList(buyerContractService.selectBizBuyerContractList(bizBuyerContractBo));
        return projectBuyerInfoVo;
    }

    /**
     * 查询文件信息
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectDocumentInfoVo documentDetail(String proId){
        String proClass = this.getProClassByProId(proId);
        if ("yfContract".equals(proClass)){
            ProjectDocumentInfoVo<BizYfContractDocument> projectDocumentInfoVo =new ProjectDocumentInfoVo();
            projectDocumentInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"document"));
            List<BizYfContractDocument> yfDocuments = yfProjectService.getYfDocumentByProId(proId);
            projectDocumentInfoVo.setProjectDocumentList(yfDocuments);
            return projectDocumentInfoVo;
        }else{
            ProjectDocumentInfoVo<BizXjProjectDocument> projectDocumentInfoVo =new ProjectDocumentInfoVo();
            projectDocumentInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"document"));

            //文件信息
            VProjectDocumentBo fileBo = new VProjectDocumentBo();
            fileBo.setProjectId(proId);
            fileBo.setProjectClass(proClass);
//            projectDocumentInfoVo.setBizXjProjectDocumentList(documentService.getFileList(fileBo));
            projectDocumentInfoVo.setProjectDocumentList(documentService.getFileList(fileBo));
            return projectDocumentInfoVo;
        }

    }

    /**
     * 查询衍生成果
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectAchievementInfoVo achievementDetail(String proId){
        ProjectAchievementInfoVo projectAchievementInfoVo = new ProjectAchievementInfoVo();
        projectAchievementInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"achievement"));

        //衍生成果记录
        projectAchievementInfoVo.setAllAchievementVOList(allAchievementService.selectByProjectId(proId));
        return projectAchievementInfoVo;
    }

    /**
     * 查询校级执行过程
     * @param proId 项目号
     * @return
     */
    @Override
    public ProjectProcessInfoVo processDetail(String proId){
        String proClass = this.getProClassByProId(proId);
        ProjectProcessInfoVo projectProcessInfoVo =new ProjectProcessInfoVo();
        projectProcessInfoVo.setProInitOtherBaseInfoVo(getProOtherInfo(proId,"process"));

        //项目变更
        AlterationBo alterationBo = new AlterationBo();
        alterationBo.setProClass(proClass);
        alterationBo.setProId(proId);
        projectProcessInfoVo.setBizProjectAlterationVoList(alterationService.selectBizProjectAlterationList(alterationBo,"export").getRecords());

        MiddleCheckOrCompleteBo bizProjectMiddleCheck = new MiddleCheckOrCompleteBo();
        bizProjectMiddleCheck.setProClass(proClass);
        bizProjectMiddleCheck.setProId(proId);
        //项目中检
        projectProcessInfoVo.setBizProjectMiddleCheckVoList(middleCheckService.selectBizProjectMiddleCheckList(bizProjectMiddleCheck,"export").getRecords());
        //项目结项
        projectProcessInfoVo.setBizProjectCompleteVoList(completeProService.selectBizProjectCompleteList(bizProjectMiddleCheck,"export").getRecords());

        return projectProcessInfoVo;
    }
    //endregion

    //region 保存

    //region 校级(基础、成员、文件)
    /**
     * 保存校级项目基础信息（业务处理）
     * @param bizXjProject
     * @return
     */
    public AjaxResult saveXjProInfos(BizXjProject bizXjProject){
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String proId = "";

        String res = "";
        try{
            bizXjProject.setLasteditdate(dateFormat.parse(dateFormat.format(date)));
            bizXjProject.setLasteditusername(loginUser.getNickName());
            bizXjProject.setLastedituserid(loginUser.getUserRealId());

            //处理结项时间、开始日期
            bizXjProject.setActualEndDate(StringUtils.isNotBlank(bizXjProject.getActualEndDate())?bizXjProject.getActualEndDate():null);
            bizXjProject.setBeginDate(StringUtils.isNotBlank(bizXjProject.getBeginDate())?bizXjProject.getBeginDate():null);

            List<DmProjectType> list = projectTypeService.selectDmProjectTypeList(bizXjProject.getProjectTypeCode(), null, null, null);
            if (list != null && list.size()>0){
                DmProjectType proTypeNow = list.get(0);
                if(StringUtils.isNotBlank(String.valueOf(proTypeNow.getTypeLevel()))){
                    //处理主项目分类id
                    String maxCode = projectTypeService.getMaxPrefix("xJProject",String.valueOf(proTypeNow.getTypeLevel()),proTypeNow.getUpCode());
                    bizXjProject.setMainProjectTypeCode(maxCode.substring(0, maxCode.length() - proTypeNow.getTypeLevel() * 2));
                    //处理项目级别字段（根据项目分类取的）
                    bizXjProject.setProjectLevelId(proTypeNow.getProjectLevelId());
                }
            }

            //各类时间判断格式（立项日期、开始日期、计划结项日期、）
            if(this.isTimeRight(bizXjProject.getAuthorizeDate(),bizXjProject.getBeginDate(),bizXjProject.getPlanEndDate())){
                return AjaxResult.error("保存失败，时间格式错误！");
            }

            int baseRes = 0;
            String completeStatus = bizXjProject.getCompletedatastatus();
            if(StringUtils.isNotBlank(completeStatus)){
                bizXjProject.setCreatedate(dateFormat.parse(dateFormat.format(date)));
                bizXjProject.setCreateuserid(loginUser.getUserRealId());
                bizXjProject.setCreateusername(loginUser.getNickName());

                bizXjProject.setCheckstatus("-2"); //申报过来的数据审核状态为-2（待完善）

                //不为空时是申报过来的项目,直接新建基础信息(成员信息、预算信息分别调接口)
                xjProjectMapper.insert(bizXjProject);
                return AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS);
            }else{
                //处理各类金额单位为元(批准经费、配套经费、外拨经费、自筹经费)
                bizXjProject.setFeeAuthorize(this.changeMoneyQuantifier(bizXjProject.getFeeAuthorize(),"*"));
                bizXjProject.setAttachFee(this.changeMoneyQuantifier(bizXjProject.getAttachFee(),"*"));
                bizXjProject.setOutFee(this.changeMoneyQuantifier(bizXjProject.getOutFee(),"*"));
                bizXjProject.setSelfProvideFee(this.changeMoneyQuantifier(bizXjProject.getSelfProvideFee(),"*"));

                //根据项目分类获取预算id
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式
                bizXjProject.setBudgetStandardId(budgetStandardService.getYsbzIdByxmflId(bizXjProject.getProjectTypeCode(),formatter.parse(bizXjProject.getAuthorizeDate())));

                if(StringUtils.isNotBlank(bizXjProject.getId())){
                    //编辑-》1、分类更改预算清空 2、负责人变更成员表更改 3、总经费改变预算清空
                    //1+3、判断项目分类的更改情况和总预算更改情况如果项目分类更改，原预算信息删除
                    String newProType = bizXjProject.getProjectLevelId();
                    BizXjProject oldInfos = this.xjDetail(bizXjProject.getId());
                    if(this.changeProLevelOrTotalFee(bizXjProject.getId(),newProType,oldInfos.getProjectLevelId(),bizXjProject.getFeeAuthorize(),oldInfos.getFeeAuthorize())){
                        //处理原预算信息成功
                        //2、处理负责人，如果负责人变了，要把新的负责人当成员表的第一条数据（类似横向的负责人变更）
                        if(this.changeFzrInfo(bizXjProject.getId(),"xJProject",bizXjProject.getChargerType(),oldInfos.getChargerType(),bizXjProject.getChargerCode(),
                                oldInfos.getChargerCode(),bizXjProject.getChargerName(),oldInfos.getChargerName())){
                            proId = xjProjectMapper.updateById(bizXjProject) >0 ?bizXjProject.getId():"";
                        }else{
                            return AjaxResult.warn("处理负责人信息失败！");
                        }
                    }else{
                        return AjaxResult.warn("处理原预算信息失败！");
                    }
                }else{
                    //生成主键id
                    String uuid = IdUtils.simpleUUID();
                    bizXjProject.setId(uuid);

                    bizXjProject.setCreatedate(dateFormat.parse(dateFormat.format(date)));
                    bizXjProject.setCreateuserid(loginUser.getUserRealId());
                    bizXjProject.setCreateusername(loginUser.getNickName());
                    bizXjProject.setCompletedatastatus("");//只要通过页签进行编辑，Completedatastatus都为空

                    bizXjProject.setAuthorpids(bizXjProject.getChargerCode()); //把负责人id存到成员id字段
                    bizXjProject.setAuthorunitids(bizXjProject.getUnitId());
                    baseRes = xjProjectMapper.insert(bizXjProject);
                    if(baseRes > 0){
                        proId = uuid;

                        //新建时要再成员表新建一条负责人成员信息
                        memberService.saveFzrByProId(proId,"xj");
                    }
                }

                return StringUtils.isNotBlank(proId)?this.saveAndCheck(proId,bizXjProject.getSubmitType(),bizXjProject.getTaskId()) :AjaxResult.error(BizProcessMessages.SAVE_FAIL);
            }

        }catch (Exception ex){
            String exStr = ex.getMessage();
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }
    }

    /**
     * 保存校级项目成员信息
     * @param xjProjectMemberList
     * @return
     */
    public AjaxResult saveXjMember(ProjectTabListBo<BizXjProjectMember> xjProjectMemberList ){
        String saveRes = memberService.saveXjMemberInfos(xjProjectMemberList.getSlaveTableList());
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(xjProjectMemberList.getProId(),xjProjectMemberList.getSubmitType(),xjProjectMemberList.getTaskId());
        }
    }

    /**
     * 保存校级文件信息
     * @param projectTabListBo
     * @return
     */
    public AjaxResult saveXjFile(ProjectTabListBo<BizXjProjectDocument> projectTabListBo){
        String saveRes = documentService.saveXJDocumentInfo(projectTabListBo);
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(projectTabListBo.getProId(),projectTabListBo.getSubmitType(),projectTabListBo.getTaskId());
        }
    }
    //endregion

    //region 纵向(基础、成员、文件、课题、单位)
    /**
     * 保存纵向项目基础信息
     * @param bizZxProject
     * @param type
     * @return
     */
    public AjaxResult saveZxProInfos(BizZxProject bizZxProject,String type){
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String proId = "";
        if(this.isTimeRight(bizZxProject.getAuthorizeDate(),bizZxProject.getBeginDate(),bizZxProject.getPlanEndDate())){
            return AjaxResult.error("保存失败，时间格式错误！");
        }

        try{
            bizZxProject.setLasteditdate(dateFormat.parse(dateFormat.format(date)));
            bizZxProject.setLasteditusername(loginUser.getNickName());
            bizZxProject.setLastedituserid(loginUser.getUserRealId());

            //处理各类金额单位为元(总经费、学校资助经费、外拨经费、拨款经费)
            bizZxProject.setFeeAuthorize(this.changeMoneyQuantifier(bizZxProject.getFeeAuthorize(),"*"));
            bizZxProject.setAttachFee(this.changeMoneyQuantifier(bizZxProject.getAttachFee(),"*"));
            bizZxProject.setOutFee(this.changeMoneyQuantifier(bizZxProject.getOutFee(),"*"));
            bizZxProject.setSelfProvideFee(this.changeMoneyQuantifier(bizZxProject.getSelfProvideFee(),"*"));

            //处理结项时间、开始日期
            bizZxProject.setActualEndDate(StringUtils.isNotBlank(bizZxProject.getActualEndDate())?bizZxProject.getActualEndDate():null);
            bizZxProject.setBeginDate(StringUtils.isNotBlank(bizZxProject.getBeginDate())?bizZxProject.getBeginDate():null);

            //根据项目分类获取预算id
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式
            bizZxProject.setBudgetStandardId(budgetStandardService.getYsbzIdByxmflId(bizZxProject.getProjectTypeCode(),formatter.parse(bizZxProject.getAuthorizeDate())));

            List<DmProjectType> list = projectTypeService.selectDmProjectTypeList(bizZxProject.getProjectTypeCode(), null, null, null);
            if (list != null && list.size()>0){
                DmProjectType proTypeNow = list.get(0);
                if(StringUtils.isNotBlank(String.valueOf(proTypeNow.getTypeLevel()))){
                    //处理主项目分类id
                    String maxCode = projectTypeService.getMaxPrefix("zXProject",String.valueOf(proTypeNow.getTypeLevel()),proTypeNow.getUpCode());
                    bizZxProject.setMainProjectTypeCode(maxCode.substring(0, maxCode.length() - proTypeNow.getTypeLevel() * 2));
                    //处理项目级别字段（根据项目分类取的）
                    bizZxProject.setProjectLevelId(proTypeNow.getProjectLevelId());
                }
            }

            //如果负责人类型是校外，则负责人id为空
            if(bizZxProject.getChargerType().equals("3")){
                bizZxProject.setChargerCode("");
            }

            int baseRes = 0;
            if(type.equals("all")){
                //有id但是也是新建
                bizZxProject.setCreatedate(dateFormat.parse(dateFormat.format(date)));
                bizZxProject.setCreateuserid(loginUser.getUserRealId());
                bizZxProject.setCreateusername(loginUser.getNickName());

                baseRes = zxProjectMapper.insert(bizZxProject);
                if(baseRes > 0){
                    //新建时要在成员表新建一条负责人成员信息
                    memberService.saveFzrByProId(bizZxProject.getId(),"zx");
                }
                return AjaxResult.success(BizProcessMessages.OPERATE_SUCCESS);
            }else
            {
                if(StringUtils.isNotBlank(bizZxProject.getId())){
                    //编辑-》1、分类更改预算清空 2、负责人变更成员biang更改 3、总经费改变预算清空
                    //1+3、判断项目分类的更改情况和总预算更改情况如果项目分类更改，原预算信息删除
                    String newProType = bizZxProject.getProjectLevelId();
                    BizZxProject oldInfos = this.zxDetail(bizZxProject.getId());
                    if(this.changeProLevelOrTotalFee(bizZxProject.getId(),newProType,oldInfos.getProjectLevelId(),bizZxProject.getFeeAuthorize(),oldInfos.getFeeAuthorize())){
                        //处理原预算信息成功
                        //2、处理负责人，如果负责人变了，要把新的负责人当成员表的第一条数据（类似横向的负责人变更）->负责人可能变成校外，code就为空了
                        if(this.changeFzrInfo(bizZxProject.getId(),"zXProject",bizZxProject.getChargerType(),oldInfos.getChargerType(),bizZxProject.getChargerCode(),oldInfos.getChargerCode(),
                                bizZxProject.getChargerName(),oldInfos.getChargerName())){
                            bizZxProject.setChargerPhone(StringUtils.isNotBlank(bizZxProject.getChargerPhone())?bizZxProject.getChargerPhone():"");
                            bizZxProject.setChargerEmail(StringUtils.isNotBlank(bizZxProject.getChargerEmail())?bizZxProject.getChargerEmail():"");

                            proId = zxProjectMapper.updateById(bizZxProject) > 0?bizZxProject.getId():"";
                        }else{
                            return AjaxResult.warn("处理负责人信息失败！");
                        }
                    }else{
                        return AjaxResult.warn("处理原预算信息失败！");
                    }
                }else{
                    //生成主键id
                    String uuid = IdUtils.simpleUUID();
                    bizZxProject.setId(uuid);

                    bizZxProject.setCreatedate(dateFormat.parse(dateFormat.format(date)));
                    bizZxProject.setCreateuserid(loginUser.getUserRealId());
                    bizZxProject.setCreateusername(loginUser.getNickName());

                    bizZxProject.setAuthorpids(bizZxProject.getChargerCode());
                    bizZxProject.setAuthorunitids(bizZxProject.getUnitId());
                    bizZxProject.setCheckstatus("-1");
                    bizZxProject.setCompletedatastatus("");//只要通过页签进行编辑，Completedatastatus都为空

                    baseRes = zxProjectMapper.insert(bizZxProject);
                    if(baseRes > 0){
                        proId = uuid;
                        //新建时要再成员表新建一条负责人成员信息
                        memberService.saveFzrByProId(proId,"zx");
                    }
                }
                return StringUtils.isNotBlank(proId)?this.saveAndCheck(proId,bizZxProject.getSubmitType(),bizZxProject.getTaskId()):AjaxResult.error(BizProcessMessages.SAVE_FAIL);
            }

        }catch (Exception ex){
            String exMessage = ex.getMessage();
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }
    }

    /**
     * 保存校级项目成员信息
     * @param zxProjectMemberList
     * @return
     */
    public AjaxResult saveZxMember(ProjectTabListBo<BizZxProjectMember> zxProjectMemberList){
        String saveRes = memberService.saveZxMemberInfos(zxProjectMemberList.getSlaveTableList());
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(zxProjectMemberList.getProId(),zxProjectMemberList.getSubmitType(),zxProjectMemberList.getTaskId());
        }
    }

    /**
     * 保存纵向文件信息
     * @param projectTabListBo
     * @return
     */
    public AjaxResult saveZxFile(ProjectTabListBo<BizZxProjectDocument> projectTabListBo){
        String saveRes = documentService.saveZXDocumentInfo(projectTabListBo);
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(projectTabListBo.getProId(),projectTabListBo.getSubmitType(),projectTabListBo.getTaskId());
        }
    }

    /**
     * 保存校内课题信息
     * @param projectTabListBo
     * @return
     */
    public AjaxResult saveKetiList(ProjectTabListBo<BizProjectInSchool> projectTabListBo){
        String saveRes = projectInSchoolService.saveKetiList(projectTabListBo);
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(projectTabListBo.getProId(),projectTabListBo.getSubmitType(),projectTabListBo.getTaskId());
        }
    }

    /**
     * 保存合作单位信息
     * @param cooperateUnitBo
     * @return
     */
    public AjaxResult saveCooperUnit(CooperateUnitBo cooperateUnitBo){
        String saveRes = projectCooperationUnitService.saveCooperUnitList(cooperateUnitBo);
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(cooperateUnitBo.getProId(),cooperateUnitBo.getSubmitType(),cooperateUnitBo.getTaskId());
        }
    }
    //endregion

    /**
     * 保存预算信息
     * @param projectBudgetBo
     * @return
     */
    public AjaxResult saveBudget(ProjectBudgetBo projectBudgetBo){
        String saveRes = budgetService.saveBudgetInfos(projectBudgetBo,"all");
        if(saveRes.contains("失败")){
            return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
        }else{
            return saveAndCheck(projectBudgetBo.getBizProjectBudgetBatch().getProjectId(),projectBudgetBo.getBizProjectBudgetBatch().getSubmitType(),projectBudgetBo.getBizProjectBudgetBatch().getTaskId());
        }
    }

    //endregion

    //region 其他公共方法
    /**
     * 获取各个页签上方的项目信息(报销金额还没写)
     * @param proId
     * @param type
     * @return
     */
    public ProInitOtherBaseInfoVo getProOtherInfo(String proId,String type){
        try{
            ProInitOtherBaseInfoVo proInitOtherBaseInfoVo = projectInitMapper.getOtherInfos(proId);

            //单独取部分页签的附件
            if(type.equals("budget")){
                //预算页扫描件
                List<ProInitOtherBaseInfoVo.OtherFilesVo> otherFilesVo = projectInitMapper.getOtherFiles(proId);
                if(otherFilesVo != null){
                    proInitOtherBaseInfoVo.setFileInfos(otherFilesVo);
                }
            }

            //增加有无出账合同的判断
            BizBuyerContractBo bizBuyerContractBo = new BizBuyerContractBo();
            bizBuyerContractBo.setSourceProjectID(proId);
            List<BizBuyerContract> buyerList = buyerContractService.selectBizBuyerContractList(bizBuyerContractBo);
            if(buyerList != null && buyerList.size()>0){
                proInitOtherBaseInfoVo.setIsThereBuyer("1");
            }

            //增加有无未通过审核的变更、中检、结项申请的判断
            //增加审核需要的字段：实例id，审核状态，审核人
            Map<String,String> businessFlag = new HashMap<>();
            if(type.equals("all")){
                //变更
                String alteration = "0";
                List<Map<String,String>> changeListByCheck = projectInitMapper.selectListByCon("biz_project_alteration",proId,"2");
                if(changeListByCheck != null && changeListByCheck.size()>0){
                    alteration = "2";//存在未通过审核的变更数据
                }else{
                    List<Map<String,String>> changeListByID = projectInitMapper.selectListByCon("biz_project_alteration",proId,null);
                    if(changeListByID != null && changeListByID.size()>0){
                        alteration ="1";//存在变更数据
                    }
                }
                businessFlag.put("变更",alteration);

                //中检
                List<Map<String,String>> middleCheckListByCheck = projectInitMapper.selectListByCon("biz_project_middle_check",proId,"2");
                String middleCheck = "0";
                if(middleCheckListByCheck != null && middleCheckListByCheck.size()>0){
                    middleCheck = "2";//存在未通过审核的中检数据
                }else{
                    List<Map<String,String>> middleCheckListByID = projectInitMapper.selectListByCon("biz_project_middle_check",proId,null);
                    if(middleCheckListByID != null && middleCheckListByID.size()>0){
                        middleCheck = "1";//存在中检数据
                    }
                }
                businessFlag.put("中检",middleCheck);

                //结项
                List<Map<String,String>> completeListByID = projectInitMapper.selectListByCon("biz_project_complete",proId,null);
                String complete = "0";
                if(completeListByID != null && completeListByID.size()>0){
                    complete = "2";//存在结项数据
                    //存在结项数据时，把结项的id传给前端用来查看结项详情
                    proInitOtherBaseInfoVo.setCompleteId(completeListByID.get(0).get("ID"));
                }
                businessFlag.put("结项",complete);

                //调账
                List<Map<String,String>> alterByID = projectInitMapper.selectListByCon("biz_budget_alteration",proId,"2");
                String alter = "0"; //申请
                if(alterByID != null && alterByID.size()>0){
                    alter = "2";//查看
                }else{
                    alterByID = projectInitMapper.selectListByCon("biz_budget_alteration",proId,null);
                    if(alterByID != null && alterByID.size()>0){
                        alter = "1";//申请，查看
                    }
                }
                businessFlag.put("调账",alter);

                //外拨,外拨没有有单查看
                if(proInitOtherBaseInfoVo.getProjectClass().equals("zXProject") && proInitOtherBaseInfoVo.getOutFee().signum() != 0){
                    List<Map<String,String>> outboundByID = projectInitMapper.selectListByCon("biz_project_outbound_main",proId,null);
                    String outbound = "0"; //申请
                    if(outboundByID != null && outboundByID.size()>0){
                        outbound = "1";//申请,查看
                    }
                    businessFlag.put("外拨",outbound);
                }

                //经费报销,没有有单查看
               List<Map<String,String>> payoutByID = projectInitMapper.selectListByCon("biz_project_payout",proId,null);
                String payout = "0"; //申请
                if(payoutByID != null && payoutByID.size()>0){
                    payout = "1";//申请,查看
                }
                businessFlag.put("报销",payout);

                proInitOtherBaseInfoVo.setBusinessFlag(businessFlag);
            }

            return proInitOtherBaseInfoVo;
        }catch (Exception exception){
            String ex = exception.getMessage();
            return new ProInitOtherBaseInfoVo();
        }
    }

    /**
     * 根据项目号判断项目类型，调不同的接口
     * @param proId
     * @return
     */
    public String getProClassByProId(String proId){
        VProject baseInfo = this.baseDetail(proId);
        if(baseInfo != null){
            return baseInfo.getProjectClass();
        }else{
            return "";
        }

    }

    /**
     * 处理其他时间字符串
     * @param dateStr
     * @param startOrEnd
     * @return
     */
    public String changeDateString(String dateStr,String startOrEnd){
        if(StringUtils.isNotBlank(dateStr)){
            int strLength = dateStr.length();
            if(startOrEnd.equals("start")){
                if(strLength == 4){
                    dateStr = dateStr + "-01-01 00:00:00";
                }else if(strLength == 7){
                    dateStr = dateStr + "-01 00:00:00";
                }
            }else{
                if(strLength == 4){
                    dateStr = dateStr + "-12-31 23:59:59";
                }else if(strLength == 7){
                    dateStr += "-01"; // 默认到每月的第一天
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    LocalDate date = LocalDate.parse(dateStr, formatter);
                    LocalDate lastDayOfMonth = date.withDayOfMonth(date.lengthOfMonth());
                    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    dateStr = lastDayOfMonth.format(outputFormatter) + " 23:59:59";
                }
            }
        }
        return dateStr;
    }

    /**
     * 给字符串加引号
     * @param oldStr
     * @return
     */
    public String addQuotationToStr(String oldStr){
        if(StringUtils.isNotBlank(oldStr)){
            String newStr = oldStr.replace(",","','");
            return newStr ;
        }else{
            return oldStr;
        }
    }

    /**
     * 修改金额单位
     * @param monetValue
     * @param type
     * @return
     */
    public String changeMoneyQuantifier(String monetValue,String type){
        String res = monetValue;
        try{

            if(StringUtils.isNotBlank(monetValue)){
                res = type.equals("*")?Double.toString(Double.parseDouble(monetValue) * 10000):Double.toString(Double.parseDouble(monetValue) / 10000);
                BigDecimal value = new BigDecimal(res);
                return value.stripTrailingZeros().toPlainString();
            }else{
                return "0";
            }
        }catch (Exception exception){
            return "0";
        }
    }

    /**
     * 修改
     * @param dateStr
     * @return
     */
    public String subeDateStr(String dateStr){
        try{
            return StringUtils.isNotBlank(dateStr)?dateStr.substring(0,10):dateStr;
        }catch (Exception exception){
            return dateStr;
        }
    }

    /**
     * 处理排序字段为大写
     * @param orderStr
     * @return
     */
    public String changeStringToUp(String orderStr){
        String res = orderStr;
        if(StringUtils.isNotBlank(orderStr)){
            try{
                // 检查字符串是否全小写
                if (orderStr.equals(orderStr.toLowerCase())) {
                    res =  orderStr.toUpperCase(); // 若全小写则转换为全大写
                }else{
                    // 否则，进行大写前加下划线的转换
                    StringBuilder result = new StringBuilder();
                    for (char c : orderStr.toCharArray()) {
                        if (Character.isUpperCase(c) && result.length() > 0) { // 遇到大写字母且不是第一个字母
                            result.append('_'); // 添加下划线
                        }
                        result.append(Character.toUpperCase(c)); // 添加大写字母
                    }

                    res = result.toString();
                }
            }catch (Exception exception){

            }
        }
        return res;
    }

    //判断项目基本信息中时间参数的格式
    public boolean isTimeRight(String authorizeDate,String beginDate,String planEndDate){
        if(!(StringUtils.isNotBlank(authorizeDate)&& middleCheckService.isValidTimeFormat(authorizeDate,"yyyy-MM-dd") && middleCheckService.isValidTimeFormat(authorizeDate,"yyyy-MM-dd HH:mm:ss"))){
            return false;
        }

        if(!(StringUtils.isNotBlank(beginDate)&& middleCheckService.isValidTimeFormat(beginDate,"yyyy-MM-dd") && middleCheckService.isValidTimeFormat(beginDate,"yyyy-MM-dd HH:mm:ss"))){
            return false;
        }

        if(!(StringUtils.isNotBlank(planEndDate)&& middleCheckService.isValidTimeFormat(planEndDate,"yyyy-MM-dd") && middleCheckService.isValidTimeFormat(planEndDate,"yyyy-MM-dd HH:mm:ss"))){
            return false;
        }

        return true;
    }
    //endregion

    //region 删除
    /**
     * 删除项目信息
     * @param proIds 项目号
     * @return
     */
    public String delInfos(String proIds){
        String res = "删除成功！";
        if(StringUtils.isNotBlank(proIds)){
            String[] proIdArray = proIds.split(",");
            String proClass = this.getProClassByProId(proIdArray[0]);
            if(proClass.equals("xJProject")){
                res = delXjInfos(proIdArray);
            }else if(proClass.equals("zXProject")){
                res = delZxInfos(proIdArray);
            }else{
                res = yfProjectService.delYfInfos(proIds);
            }
        }
        return res;
    }

    /**
     * 删除校级项目信息
     * @param proIds 项目号
     * @return
     */
    public String delXjInfos(String[] proIds){
        String res = "删除成功！";
        String[] ids = null;

        try{
            if(proIds != null && proIds.length > 0){
                for(int m =0;m< proIds.length;m++){
                    String proId = proIds[m];
                    BizXjProject baseInfo = xjProjectMapper.selectById(proId);
                    if(baseInfo != null){
                        int delBase = xjProjectMapper.deleteById(proId);//删除主表
                        if(delBase > 0) {
                            memberService.delMemberInfo(ids, proId, "xj");//删除成员信息
                            budgetService.delBudgetInfos(proId); //删除预算信息（Batch主表和Date从表）
                            documentService.deleteByProId(proId,"xJProject");//删除文件信息
                        }
                    }
                }
            }
        }catch (Exception exception){
            res = "删除基础信息失败！" + exception.getMessage();
        }
        return res;
    }

    /**
     * 删除纵向项目信息
     * @param proIds 项目号
     * @return
     */
    public String delZxInfos(String[] proIds){
        String res = "删除成功！";
        String[] ids = null;

        try{
            if(proIds != null && proIds.length>0){
                for(int m = 0;m<proIds.length;m++){
                    String proId = proIds[m];
                    BizZxProject baseInfo = zxProjectMapper.selectById(proId);
                    if(baseInfo != null){
                        int delBase = zxProjectMapper.deleteById(proId);//删除主表
                        if(delBase > 0) {
                            memberService.delMemberInfo(ids, proId, "zx");//删除成员信息
                            budgetService.delBudgetInfos(proId); //删除预算信息（Batch主表和Date从表）
                            documentService.deleteByProId(proId,"zXProject");//删除文件信息

                            projectInSchoolService.deleteByProId(proId);//删除校内课题
                            projectCooperationUnitService.deleteByProId(proId);//删除合作单位
                        }
                    }
                }
            }
        }catch (Exception exception){
            res = "删除基础信息失败！" + exception.getMessage();
        }
        return res;
    }
    //endregion

    /**
     * 项目保存并通过 + 新建时审核通过
     * @param proId 项目号
     * @param submitType 提交类型
     * @return
     */
    public AjaxResult saveAndCheck(String proId,Integer submitType, String taskId){
        try{
            if(StringUtils.isNotBlank(proId)){
                String proClass = this.getProClassByProId(proId);
                if(proClass.equals("xJProject")){
                    BizXjProject xjProject = xjProjectMapper.selectById(proId);
                    return checkCommon.upDateZBCheckInfo(xjProject,BizXjProject.class,proId,submitType,"校级项目立项", xjProject.getCheckstatus(),taskId,proClass);
                }else if(proClass.equals("zXProject")){
                    BizZxProject zxProject = zxProjectMapper.selectById(proId);
                    return checkCommon.upDateZBCheckInfo(zxProject,BizZxProject.class,proId,submitType,"纵向项目立项", zxProject.getCheckstatus(),taskId,proClass);
                }
                else{
                    BizYfContract yfContract = yfProjectService.getById(proId);
                    return checkCommon.upDateZBCheckInfo(yfContract,BizYfContract.class,proId,submitType,"进账合同签订", yfContract.getCheckstatus(),taskId,proClass);
                }
            }else{
                return AjaxResult.error(BizProcessMessages.OPERATE_FAIL);
            }
        }catch (Exception exception){
            return AjaxResult.error(BizProcessMessages.OPERATE_FAIL);
        }
    }

    /**
     * 纵向项目申请审核通过后课题都要成为新的项目，课题表写入creatFalg和subjectId; 项目编号赋值
     * @param tableName
     * @param businessId
     * @param checkStatus
     * @param sysUserId
     */
    @Override
    public void updateBusinessStatus(String tableName, String businessId, String checkStatus, String sysUserId){
        try{
            if(checkStatus.equals("2")){
                String ketiRes = projectInSchoolService.changeInSchoolInfo(businessId);

                String proCode = sysSnruleService.generateCode("2", businessId);
                BizZxProject bizZxProject = new BizZxProject();
                bizZxProject.setCode(proCode);
                bizZxProject.setId(businessId);
//                bizZxProject.setCheckstatus("2");
//                bizZxProject = ReflectionUtils.updateFields(bizZxProject, BizZxProject.class);
                zxProjectMapper.updateById(bizZxProject);
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
        }
    }

    /**
     * 项目分类改变、总经费改变时清空原预算信息
     * @param proId 项目号
     * @param newProType 新分类
     * @param oldProType 旧分类
     * @param newFee 新总经费
     * @param oldFee 旧总经费
     * @return
     */
    public boolean changeProLevelOrTotalFee(String proId,String newProType,String oldProType,String newFee,String oldFee){
        try{
            //总经费可能会因为0的问题不相等，都转换为double比较——》oldfee是万元，newfee是元且均不为空
            if(!oldProType.equals(newProType) || Double.valueOf(newFee) != Double.valueOf(oldFee) * 10000){
                //如果项目分类或总经费发生了改变，原预算信息要清空：预算主表和预算从表
                String delBudget = budgetService.delBudgetInfos(proId);
                if(delBudget.contains("失败")){
                    return false;
                }
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
            return false;
        }

        return true;
    }

    /**
     * 项目负责人变更时处理成员表
     * @param proId
     * @param proClass
     * @param newFzr
     * @param oldFzr
     * @return
     */
    public boolean changeFzrInfo(String proId, String proClass,String chargerType,String oldChargerType,String newFzr,String oldFzr,String newFzrName,String oldFzrName){
        try{
            if(!newFzr.equals(oldFzr) || !newFzrName.equals(oldFzrName) ){
                //更新负责人的方法之前写过
                //处理成员从表
                BizProjectMemberAlteration memberAlteration = new BizProjectMemberAlteration();
                memberAlteration.setPersonName(newFzrName);
                memberAlteration.setPersonId(newFzr);
                memberAlteration.setMemberType(chargerType);
                List<BizProjectMemberAlteration> list = new ArrayList<>();
                list.add(memberAlteration);
                memberService.changeMemberInfo(proId,proClass,"chargerName",list);
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
            return false;
        }

        return true;
    }
}
